﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.Windows.Threading;
using System.Xml;
using System.IO;

using Factonomy.AzureUtility.Controls;
using Factonomy.AzureUtility.Core;
using Factonomy.AzureUtility.Core.Storage;
using Factonomy.AzureUtility.Core.StorageHelpers;

namespace Factonomy.AzureUtility
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            this.Show();

            this.uiTree.RenderComplete += new NoParameterDelegate(OnAzureTreeRendered);
            this.uiTree.LoadComplete += new NoParameterDelegate(OnAzureTreeLoaded);
            this.uiTree.AccountItemClicked += new TreeViewItemHelperDelegate(OnAzureTreeAccountItemClicked);
            this.uiTree.ContainersItemClicked += new TreeViewItemHelperDelegate(OnAzureTreeContainersItemClicked);
            this.uiTree.ContainerItemClicked += new TreeViewItemHelperDelegate(OnAzureTreeContainerItemClicked);
            this.uiTree.ContainerItemClicked += new TreeViewItemHelperDelegate(this.uiInfoPanel.Show);
            this.uiTree.AccountItemClicked += new TreeViewItemHelperDelegate(this.uiInfoPanel.Show);

            BlobHelper.Instance.LoadBlobListComplete += new NoParameterDelegate(OnBlobListViewFinishedLoading);
            BlobHelper.Instance.EndTask += new NoParameterDelegate(EndTask);
            BlobHelper.Instance.StartTask += new StringParameterDelegate(StartTask);
            BlobHelper.Instance.Error += new EventHandler(BlobHelperError);
            BlobHelper.Instance.ShowStatus += new StringParameterDelegate(BlobHelperShowStatus);

            this.uiViewBlobControl.SelectedIndexChanged += new BlobPropertiesDelegate(OnBlobViewSelectedIndexChanged);
            this.uiViewBlobControl.SelectedIndexChanged += new BlobPropertiesDelegate(this.uiInfoPanel.Show);

            this.InitTree(true);
        }

        void BlobHelperShowStatus(string sender)
        {
            this.UpdateStatus(sender);
        }

        void OnBlobViewSelectedIndexChanged(BlobContainer container, BlobProperties properties)
        {
        }

        void BlobHelperError(object sender, EventArgs e)
        {
            this.CursorArrow();

            Exception ex = sender as Exception;
            string message = string.Empty;
            
            while (ex != null)
            {
                message += ex.Message + " ";
                ex = ex.InnerException;
            }

            this.UpdateStatus(((Exception)sender).Message);
            MessageBox.Show(message);
        }

        void StartTask(string sender)
        {
            this.CursorWait();
            this.UpdateStatus(sender);
        }

        private void CursorArrow()
        {
            if (this.Dispatcher.CheckAccess())
            {
                this.Cursor = Cursors.Arrow;
            }
            else
            {
                this.Dispatcher.Invoke(DispatcherPriority.Normal, new NoParameterDelegate(this.CursorArrow));
            }
        }

        private void CursorWait()
        {
            if (this.Dispatcher.CheckAccess())
            {
                this.Cursor = Cursors.Wait;
            }
            else
            {
                this.Dispatcher.Invoke(DispatcherPriority.Normal, new NoParameterDelegate(this.CursorWait));
            }
        }

        void EndTask()
        {
            if (this.Dispatcher.CheckAccess())
            {
                this.Cursor = Cursors.Arrow;
                UpdateStatus("Ready");
            }
            else
            {
                this.Dispatcher.Invoke(DispatcherPriority.Normal, new NoParameterDelegate(this.EndTask));
            }
        }

        void DeleteAllBlobsStart()
        {
            if (this.Dispatcher.CheckAccess())
            {
                this.Cursor = Cursors.Wait;
                UpdateStatus("Deleting all blobs...");
            }
            else
            {
                this.Dispatcher.Invoke(DispatcherPriority.Normal, new NoParameterDelegate(this.DeleteAllBlobsStart));
            }
        }

        void DeleteAllBlobsEnd()
        {
            if (this.Dispatcher.CheckAccess())
            {
                this.Cursor = Cursors.Arrow;
                UpdateStatus("Ready");
            }
            else
            {
                this.Dispatcher.Invoke(DispatcherPriority.Normal, new NoParameterDelegate(this.DeleteAllBlobsEnd));
            }
        }

        void OnAzureTreeContainerItemClicked(TreeViewItemHelper sender)
        {
            ConfigAccount account = Config.Instance.GetAccount(sender.AccountName);
            BlobContainer container = BlobHelper.Instance.GetContainer(account, sender.Container);

            //this.uiInfoPanel.Show(container);

            this.uiViewBlobControl.LoadContainer(container);
            this.uiViewBlobControl.Visibility = Visibility.Visible;

            this.Cursor = Cursors.Wait;
            UpdateStatus("Loading blobs data...");
            this.uiViewBlobControl.LoadBlobs();
        }

        void OnBlobListViewFinishedLoading()
        {
            if (this.Dispatcher.CheckAccess())
            {
                this.Cursor = Cursors.Arrow;
                UpdateStatus("Ready");
            }
            else
            {
                this.Dispatcher.Invoke(DispatcherPriority.Normal, new NoParameterDelegate(this.OnBlobListViewFinishedLoading));
            }
        }

        void OnAzureTreeContainersItemClicked(TreeViewItemHelper sender)
        {
            this.uiViewBlobControl.Visibility = Visibility.Hidden;
        }

        void OnAzureTreeAccountItemClicked(TreeViewItemHelper sender)
        {
            this.uiViewBlobControl.Visibility = Visibility.Hidden;
        }

        void OnAzureTreeLoaded()
        {
            UpdateStatus("Rendering storage account data...");
            this.uiTree.Render();
        }

        void OnAzureTreeRendered()
        {
            this.Cursor = Cursors.Arrow;
            UpdateStatus("Ready");
        }

        private void InitTree(object startThread)
        {
            if (bool.Parse(startThread.ToString()))
            {
                this.Cursor = Cursors.Wait;
                UpdateStatus("Loading storage account data...");
                Thread thread = new Thread(new ParameterizedThreadStart(this.InitTree));
                thread.IsBackground = true;
                thread.Start(false);
            }
            else
            {
                this.uiTree.Init();
            }
        }        

        private void UpdateStatus(object message)
        {
            if (this.uiStatusText.Dispatcher.CheckAccess())
            {
                this.uiStatusText.Text = message.ToString();
            }
            else
            {
                this.uiStatusText.Dispatcher.Invoke(DispatcherPriority.Normal, new StringParameterDelegate(this.UpdateStatus), message);
            }
        }

        private void ToggleCursor()
        {
            if (this.Dispatcher.CheckAccess())
            {
                if (this.Cursor == null || this.Cursor == Cursors.Arrow)
                {
                    this.Cursor = Cursors.Wait;
                }
                else
                {
                    this.Cursor = Cursors.Arrow;
                }
            }
            else
            {
                this.Dispatcher.Invoke(DispatcherPriority.Normal, new NoParameterDelegate(this.ToggleCursor));
            }
        }

        private void OpenSettings(object sender, RoutedEventArgs e)
        {
            Dialogs.Settings settings = new Dialogs.Settings();
            settings.Owner = this;
            settings.ShowDialog();
        }

        private void CloseWindow(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void RefreshAccounts(object sender, RoutedEventArgs e)
        {
            this.InitTree(true);
        }

        private void AddAccount(object sender, RoutedEventArgs e)
        {
            Dialogs.ManageAccount accountDialog = new Dialogs.ManageAccount(null);
            accountDialog.AccountChanged += new NoParameterDelegate(OnAccountChanged);
            accountDialog.Owner = Application.Current.Windows[0];
            accountDialog.ShowDialog();
        }

        private void EditAccount(object sender, RoutedEventArgs e)
        {
            TreeViewItemHelper helper = this.uiTree.GetSelectedHelper();
            if (helper == null)
            {
                MessageBox.Show("Please select an account.");
            }
            else
            {
                ConfigAccount account = Config.Instance.GetAccount(helper.AccountName);
                Dialogs.ManageAccount accountDialog = new Dialogs.ManageAccount(account);
                accountDialog.AccountChanged += new NoParameterDelegate(OnAccountChanged);
                accountDialog.Owner = Application.Current.Windows[0];
                accountDialog.ShowDialog();
            }
        }

        void OnAccountChanged()
        {
            this.InitTree(true);
        }

        private void RemoveAccount(object sender, RoutedEventArgs e)
        {
            TreeViewItemHelper helper = this.uiTree.GetSelectedHelper();
            if (helper == null)
            {
                MessageBox.Show("Please select an account.");
            }
            else
            {
                ConfigAccount account = Config.Instance.GetAccount(helper.AccountName);
                if (MessageBox.Show("Really delete?", "Confirm delete", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                {
                    Config.Instance.DeleteAccount(account.AccountName);
                    this.uiTree.RemoveSelectedItem();
                }
            }
        }

        private void OpenHelpAbout(object sender, RoutedEventArgs e)
        {
            Dialogs.About about = new Dialogs.About();
            about.Owner = this;
            about.ShowDialog();
        }

        //private void uiCollapseMainPanel_MouseDown(object sender, MouseButtonEventArgs e)
        //{
        //    if (this.grid1.ColumnDefinitions[0].Width == new GridLength(40))
        //    {
        //        IconBitmapDecoder decoder = new IconBitmapDecoder(ResourceManager.GetBackIcon, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
        //        this.uiCollapseMainPanelImage.Source = decoder.Frames[0];
        //        this.grid1.ColumnDefinitions[0].Width = new GridLength(300);
        //        this.uiTree.Visibility = Visibility.Visible;
        //    }
        //    else
        //    {
        //        IconBitmapDecoder decoder = new IconBitmapDecoder(ResourceManager.GetNextIcon, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
        //        this.uiCollapseMainPanelImage.Source = decoder.Frames[0];
        //        this.grid1.ColumnDefinitions[0].Width = new GridLength(40);
        //        this.uiTree.Visibility = Visibility.Hidden;
        //    }
        //}

    }
}
